package org.jeecg.modules.appPermission.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.appPermission.service.AppPermissionService;
import org.jeecg.modules.system.entity.SysPermission;
import org.jeecg.modules.system.entity.SysRole;
import org.jeecg.modules.system.entity.SysRolePermission;
import org.jeecg.modules.system.entity.SysUserRole;
import org.jeecg.modules.system.service.ISysPermissionService;
import org.jeecg.modules.system.service.ISysRolePermissionService;
import org.jeecg.modules.system.service.ISysRoleService;
import org.jeecg.modules.system.service.ISysUserRoleService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;


/**
 * @description: APP PERMISSION SERVICE IMPL
 * @author: zwf
 * @create: 2025-06-13 14:15
 **/
@Slf4j
@Service
public class AppPermissionServiceImpl implements AppPermissionService {
    @Resource
    private ISysRoleService roleService;
    @Resource
    private ISysUserRoleService userRoleService;
    @Resource
    private ISysPermissionService permissionService;
    @Resource
    private ISysRolePermissionService rolePermissionService;

    /**
     * 获取用户角色
     *
     * @author zwf
     * @date created in 2025-06-13 14:38
     * @param: loginUser
     * @return: java.util.List<org.jeecg.modules.system.entity.SysRole>
     */
    @Override
    public List<String> getUserRole(LoginUser loginUser) {
        ArrayList<String> result = new ArrayList<>();

        LambdaQueryWrapper<SysUserRole> userRoleQueryWrapper = new LambdaQueryWrapper<>();

        userRoleQueryWrapper.eq(SysUserRole::getUserId, loginUser.getId());

        List<SysUserRole> userRolelist = userRoleService.list(userRoleQueryWrapper);

        List<String> userRoles = new ArrayList<>();

        if (userRolelist != null && !userRolelist.isEmpty()) {
            userRolelist.forEach(userRole -> userRoles.add(userRole.getRoleId()));
        }

        if (!userRoles.isEmpty()) {
            // 过滤出app权限
            LambdaQueryWrapper<SysRole> roleQueryWrapper = new LambdaQueryWrapper<>();

            roleQueryWrapper.in(SysRole::getId, userRoles);
            roleQueryWrapper.eq(SysRole::getType, CommonConstant.SYSTEM_TYPE_APP);

            List<SysRole> roleList = roleService.list(roleQueryWrapper);

            if (roleList != null && !roleList.isEmpty()) {
                roleList.forEach(role -> result.add(role.getId()));
            }
        }
        return result;

    }

    /**
     * 根据角色获取用户权限
     *
     * @author zwf
     * @date created in 2025-06-13 14:39
     * @param: roleList
     * @return: java.util.List<org.jeecg.modules.system.entity.SysPermission>
     */
    @Override
    public List<SysPermission> getUserPermission(List<String> roleList) {
        List<SysPermission> result = new ArrayList<>();

        if (roleList != null && !roleList.isEmpty()) {
            LambdaQueryWrapper<SysRolePermission> rolePermissionQueryWrapper = new LambdaQueryWrapper<>();

            rolePermissionQueryWrapper.in(SysRolePermission::getRoleId, roleList);

            List<SysRolePermission> rolePermissionList = rolePermissionService.list(rolePermissionQueryWrapper);

            List<String> permissionIds = new ArrayList<>();

            rolePermissionList.forEach(rolePermission -> permissionIds.add(rolePermission.getPermissionId()));

            LambdaQueryWrapper<SysPermission> permissionQueryWrapper = new LambdaQueryWrapper<>();

            permissionQueryWrapper.in(SysPermission::getId, permissionIds);
            permissionQueryWrapper.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
            permissionQueryWrapper.eq(SysPermission::getType, CommonConstant.SYSTEM_TYPE_APP);
            permissionQueryWrapper.orderByAsc(SysPermission::getSortNo);

            result = permissionService.list(permissionQueryWrapper);
        }
        return result;
    }

    @Override
    public JSONObject packagePermission(List<SysPermission> permissionList) {
        JSONObject result = new JSONObject();

        // 过滤一级菜单 (menu_type=0)
        List<SysPermission> firstLevelMenus = permissionList.stream()
                .filter(permission -> permission.getMenuType() != null && permission.getMenuType() == 0)
                .toList();
        // 构建扁平化菜单结构
        for (SysPermission menu : firstLevelMenus) {
            // 获取二级菜单
            List<SysPermission> secondLevelMenus = permissionList.stream()
                    .filter(permission -> menu.getId().equals(permission.getParentId()))
                    .toList();

            for (SysPermission secondMenu : secondLevelMenus) {
                JSONArray childrenArray = new JSONArray();

                // 获取三级菜单
                List<SysPermission> thirdLevelMenus = permissionList.stream()
                        .filter(permission -> secondMenu.getId().equals(permission.getParentId()))
                        .toList();

                for (SysPermission thirdMenu : thirdLevelMenus) {
                    JSONObject menuJson = buildMenuJson(thirdMenu);
                    childrenArray.add(menuJson);
                }

                // 使用二级菜单名称作为key
                result.put(secondMenu.getName(), childrenArray);
            }
        }
        return result;
    }

    /**
     * Build menu JSON object
     */
    private JSONObject buildMenuJson(SysPermission menu) {
        JSONObject result = new JSONObject();

        String description = menu.getDescription();

        result.put("id", menu.getId());
        result.put("name", menu.getName());
        result.put("path", menu.getUrl());
        result.put("icon", menu.getIcon());
        result.put("sort", menu.getSortNo());
        result.put("collect", description != null && description.equals("collect"));

        boolean valid = isValidObject(description);

        if (valid) {
            JSONObject object = JSON.parseObject(description);
            result.put("desc", object.getString("desc"));
            result.put("class", object.getString("class"));
            result.put("collect", object.getBoolean("collect") != null && object.getBoolean("collect"));
        }

        return result;
    }

    private Boolean isValidObject(String res) {
        if (res == null || res.isEmpty())
            return false;
        try {
            JSON.parseObject(res);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}
